package pl.edu.agh.iosr.gamblingzone.dao.hibernate;

import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projection;

import java.util.LinkedList;
import java.util.List;

/**
 * The Class ComplexCriterion.
 * <br>
 * It's a bundle of Hibernate Criterions - i.e. Projections, Order & Criterions.
 */
public class ComplexCriterion {
	
	/** The criterions. */
	List<Criterion> criterions = new LinkedList<Criterion>();
	
	/** The projections. */
	List<Projection> projections = new LinkedList<Projection>();
	
	/** The orders. */
	List<Order> orders = new LinkedList<Order>();
	
	/**
	 * Adds the criterion.
	 * 
	 * @param criterion the criterion
	 * 
	 * @return the complex criterion
	 */
	public ComplexCriterion add(Object criterion) {
		
		if (criterion instanceof Criterion) {
			this.addCriterion((Criterion)criterion);
		} else if (criterion instanceof Projection) {
			this.addProjection((Projection)criterion);
		} else if (criterion instanceof Order) {
			this.addOrder((Order)criterion);
		}
		
		return this;
	}
	
	/**
	 * Gets the criterions.
	 * 
	 * @return the criterions
	 */
	public List<Criterion> getCriterions() {
		return criterions;
	}
	
	/**
	 * Adds the criterion.
	 * 
	 * @param criterion the criterion
	 * 
	 * @return the complex criterion
	 */
	private ComplexCriterion addCriterion(Criterion criterion) {
		this.criterions.add(criterion);
		
		return this;
	}
	
	/**
	 * Gets the projections.
	 * 
	 * @return the projections
	 */
	public List<Projection> getProjections() {
		return projections;
	}
	
	/**
	 * Adds the projection.
	 * 
	 * @param projection the projection
	 * 
	 * @return the complex criterion
	 */
	private ComplexCriterion addProjection(Projection projection) {
		this.projections.add(projection);
		
		return this;
	}
	
	/**
	 * Gets the orders.
	 * 
	 * @return the orders
	 */
	public List<Order> getOrders() {
		return orders;
	}
	
	/**
	 * Adds the order.
	 * 
	 * @param order the order
	 * 
	 * @return the complex criterion
	 */
	private ComplexCriterion addOrder(Order order) {
		this.orders.add(order);
		
		return this;
	}
	
	
}
